package com.gipson.amc.config.security;

import com.gipson.amc.entity.Authority;
import com.gipson.amc.entity.Role;
import com.gipson.amc.entity.User;
import com.gipson.amc.service.basicdata.AuthorityService;
import com.gipson.amc.service.basicdata.RoleService;
import com.gipson.amc.service.basicdata.UserService;
import com.gipson.amc.utils.PropertyUtil;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.AllowAllCredentialsMatcher;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.client.RestTemplate;

import java.util.List;

public class EnceladusShiroRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private AuthorityService authorityService;

    @Autowired
    private RestTemplate restTemplate;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

        User user = (User) principals.getPrimaryPrincipal();

        List<Role> roleList = roleService.getRolesByUsername(user.getUsername());

        for (Role role : roleList) {
            authorizationInfo.addRole(role.getRoleCode());
            List<Authority> authorities = authorityService.listByRoleId(role.getId());
            authorities.stream().filter(x->Authority.TYPE_PERMISSON.equals(x.getType())).forEach(x-> authorizationInfo.addStringPermission(x.getPermission()));
        }
        return authorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = (String) token.getPrincipal();
        User user = userService.findUserByName(username);
        user.setPasswordShown(String.valueOf((char[])token.getCredentials()) );
        String applicationId = PropertyUtil.getApplicationId();
        if (user == null) {
            return null;
        }

        user.setMenus(authorityService.getAllMenuByUsername(user.getUsername(),applicationId));

        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user, user.getPassword(),
                ByteSource.Util.bytes(user.getSalt()), getName());
        return authenticationInfo;
    }

    /*@Override
    protected void assertCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) throws AuthenticationException {
        CredentialsMatcher cm = getCredentialsMatcher();
        if (cm != null) {
            if (!cm.doCredentialsMatch(token, info)) {
                //not successful - throw an exception to indicate this:
                String msg = "Submitted credentials for token [" + token + "] did not match the expected credentials.";
                throw new IncorrectCredentialsException(msg);
            }
        } else {
            throw new AuthenticationException("A CredentialsMatcher must be configured in order to verify " +
                    "credentials during authentication.  If you do not wish for credentials to be examined, you " +
                    "can configure an " + AllowAllCredentialsMatcher.class.getName() + " instance.");
        }
    }*/
}
